package com.rui.study.commons.study;

import com.rui.study.commons.model.Result;
import com.rui.study.commons.study.aop.Advisor;
import com.rui.study.commons.study.aop.JDKDynamicProxy;
import com.rui.study.commons.study.aop.TargetSource;
import com.rui.study.commons.study.http.AbstractConcurrentRequest;
import com.rui.study.commons.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.*;

import java.awt.print.Book;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

public class Main implements Test {

    private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);



    /**************************************************
     *                 TEST METHOD                  *
     **************************************************/

    public void testDateUtil() {
        LOGGER.info(DateUtil.now());
    }

    public void testBeanUtil() {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("status", "101");
        map.put("desc", "woqu");
        map.put("message", "走你");
        map.put("con", "...");

        Result object = BeanUtil.buildBean(map, Result.class);
        LOGGER.info(object.toString());
    }

    public void testJsonUtil() {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("status", "101");
        map.put("desc", "woqu");
        map.put("message", "走你");
        map.put("con", "...");
        String str = JsonUtil.toJson(map);
        LOGGER.info(str);
    }

    public void testMD5Util() {
        LOGGER.info(MD5Util.encrypt("111111"));
    }

    @Override
    public void testNewInstance() {
        try {
            Class clazz = Book.class;
//            Class clazz = Class.forName("com.rui.study.algorithm.test_newinstance.Book");
            LOGGER.info("ClassLoader for Book: {}", clazz.getClassLoader());
            Book book = (Book) clazz.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void testClassLoader() {
        LOGGER.info("ClassLoader: {}", ClassLoader.getSystemClassLoader());
        LOGGER.info("ClassLoader: {}", ClassLoader.getSystemClassLoader().getParent());
        LOGGER.info("ClassLoader: {}", ClassLoader.getSystemClassLoader().getParent().getParent());

        ClassLoader classLoader = new ClassLoader() {
            @Override
            protected Class<?> findClass(String name) throws ClassNotFoundException {
                return super.findClass(name);
            }
        };
    }

    @Override
    public void testRandomName() {
        int count = 50;
        while(count-- > 0) {
            LOGGER.info("Random name >>> {}", RandomUtil.nextCNChar() + RandomUtil.nextCNChar() + RandomUtil.nextCNChar() + RandomUtil.nextCNChar());
        }
    }

    @Override
    public void testConcurrentHTTPRequest() {
        AbstractConcurrentRequest request = new AbstractConcurrentRequest(1000) {
            @Override
            protected RequestEntity buildRequestEntity() {
                try {
                    URI uri = new URI("http://172.16.5.16:11999/uasc/user/v1/register");
                    String organization = RandomUtil.nextWord(2, 5, "CN");
                    String email = RandomUtil.nextEmail();
                    String json = "{\n" +
                            "\t\"userInfoDo\": {\n" +
                            "\t\t\"type\": \"机构\",\n" +
                            "\t\t\"regionState\": \"中国\",\n" +
                            "\t\t\"regionProvince\": \"广东\",\n" +
                            "\t\t\"industry1\": \"IT\",\n" +
                            "\t\t\"industry2\": \"电子商务\",\n" +
                            "\t\t\"orgName\": \"" + organization + "\",\n" +
                            "\t\t\"logoPath\": \"http://172.16.5.16:9191/logo/hehe.png\",\n" +
                            "\t\t\"address\": \"南海大道1003\",\n" +
                            "\t\t\"orgCode\": \"101645778234\",\n" +
                            "\t\t\"cerScanPath\": \"http://172.16.5.16:9191/logo/gg.png\",\n" +
                            "\t\t\"officialWebsite\": \"www.wahaha.com\"\n" +
                            "\t\t\n" +
                            "\t},\n" +
                            "\t\"contactsInfoDo\": {\n" +
                            "\t\t\"name\": \"老王\",\n" +
                            "\t\t\"telephone\": \"0755-12344312\",\n" +
                            "\t\t\"cellPhone\": \"+86 13512344312\",\n" +
                            "\t\t\"position\": \"销售总监\",\n" +
                            "\t\t\"email\": \"" + email + "\",\n" +
                            "\t\t\"address\": \"环球数码大厦A15\",\n" +
                            "\t\t\"postcode\": \"030001\"\n" +
                            "\t},\n" +
                            "\t\"accountInfoDo\": {\n" +
                            "\t\t\"email\": \"" + email + "\",\n" +
                            "\t\t\"password\": \"a123456\",\n" +
                            "\t\t\"verifyCode\": \"8888\"\n" +
                            "\t}\n" +
                            "}";
                    HttpHeaders headers = new HttpHeaders();
                    headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
                    return new RequestEntity(json, headers, HttpMethod.PUT, uri);
                } catch (URISyntaxException e) {
                    throw new RuntimeException();
                }
            }

            @Override
            protected void processAggregationResult(ResponseEntity<?> result, String threadName, AggregationResult aggregationResult) {
                Object obj = result.getBody();
                if (obj instanceof String) {
                    processListResult("USER_REGISTER", obj, aggregationResult);
                }
            }
        };
        // 并发请求
        AbstractConcurrentRequest.AggregationResult aggregation = request.concurrencyExchange(String.class);
        // 处理结果
        LinkedList<String> jsonResultList = (LinkedList<String>) aggregation.getAttribute("USER_REGISTER");
        for (String jsonResult : jsonResultList) {
            LOGGER.info("Result>>>>>>>>>>: {}", jsonResult);
        }
    }

    @Override
    public void testFtpFileUpload() {
        File file = new File("C:\\Users\\Public\\Pictures\\Sample Pictures\\like.jpg");
        try {
            boolean result = FtpFileUtil.uploadFile("hehe.png", new FileInputStream(file));
            LOGGER.info("result: {}", result);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**************************************************
     *                  INNER CLASS                   *
     **************************************************/

    private class InternalAdvisor implements Advisor {

        private long startTime;

        private long endTime;

        @Override
        public Object before() {
            startTime = System.currentTimeMillis();
            return null;
        }

        @Override
        public Object after() {
            endTime = System.currentTimeMillis();
            double duration = (endTime - startTime) / 1000D;
            LOGGER.info("Duration: [{}s]", duration);
            return null;
        }

        @Override
        public Object onException() {
            return null;
        }

        @Override
        public Object onFinal() {
            return null;
        }

    }

    /**************************************************
     *                     MAIN                       *
     **************************************************/
    public static void main(String[] args) {
        Main main = new Main();
        TargetSource targetSource = new TargetSource(main, Test.class);
        Advisor advisor = main.new InternalAdvisor();
        JDKDynamicProxy jdkDynamicProxy = new JDKDynamicProxy(targetSource, advisor);
        Test test = (Test) jdkDynamicProxy.getProxy();

//        test.testMD5Util();
//        test.testBeanUtil();
//        test.testDateUtil();
//        test.testJsonUtil();
//        test.testNewInstance();
//        test.testClassLoader();
//        test.testTwoVarExchange();
//        test.testRandomName();
        test.testConcurrentHTTPRequest();
//        test.testFtpFileUpload();


//        LOGGER.info(""  + System.currentTimeMillis());
    }

}
